home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / public / Xpm / pixmap / PixEdit.c < prev    next >
C/C++ Source or Header  |  1994-08-01  |  59KB  |  2,206 lines

  1. /*
  2.  * $Id: PixEdit.c,v 1.10 1992/10/28 12:26:23 mallet Exp $
  3.  * 
  4.  * Copyright 1991 Lionel Mallet
  5.  * 
  6.  * Permission to use, copy, modify, distribute, and sell this software and its
  7.  * documentation for any purpose is hereby granted without fee, provided that
  8.  * the above copyright notice appears in all copies and that both that
  9.  * copyright notice and this permission notice appear in supporting
  10.  * documentation, and that the name of Lionel MALLET not be used in
  11.  * advertising or publicity pertaining to distribution of the software
  12.  * without specific, written prior permission.  Lionel MALLET makes no
  13.  * representations about the suitability of this software for any
  14.  * purpose.  It is provided "as is" without express or implied warranty.
  15.  *
  16.  * Lionel MALLET DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS
  17.  * SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
  18.  * FITNESS, IN NO EVENT SHALL Lionel MALLET BE LIABLE FOR ANY SPECIAL,
  19.  * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
  20.  * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION 
  21.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  22.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  23.  *
  24.  *  This software is opened and free. Furthermore, everybody is kindly
  25.  * invited to participate to improve it for the benefit of all.
  26.  * Improvements can be new features, bugs fixes and porting issues
  27.  * resolution.
  28.  *
  29.  * Author:  Lionel Mallet, SIMULOG
  30.  */
  31.  
  32. /*
  33.  * $XConsortium: BitEdit.c,v 1.7 90/06/09 20:19:19 dmatic Exp $
  34.  *
  35.  * Copyright 1989 Massachusetts Institute of Technology
  36.  *
  37.  * Permission to use, copy, modify, distribute, and sell this software and its
  38.  * documentation for any purpose is hereby granted without fee, provided that
  39.  * the above copyright notice appear in all copies and that both that
  40.  * copyright notice and this permission notice appear in supporting
  41.  * documentation, and that the name of M.I.T. not be used in advertising or
  42.  * publicity pertaining to distribution of the software without specific,
  43.  * written prior permission.  M.I.T. makes no representations about the
  44.  * suitability of this software for any purpose.  It is provided "as is"
  45.  * without express or implied warranty.
  46.  *
  47.  * M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
  48.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
  49.  * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  50.  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION
  51.  * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
  52.  * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  53.  *
  54.  * Author:  Davor Matic, MIT X Consortium
  55.  */
  56.  
  57. static char rcsid[] = "$Id: PixEdit.c,v 1.10 1992/10/28 12:26:23 mallet Exp $";
  58.  
  59.  
  60. #include <stdio.h>
  61. #include <X11/Intrinsic.h>
  62. #include <X11/Xos.h>
  63. #include <X11/Xfuncs.h>
  64. #include <X11/StringDefs.h>
  65. #include <X11/extensions/shape.h>
  66. #ifndef USE_ATHENA
  67. #include <Xm/Xm.h>
  68. #include <Xm/RowColumn.h>
  69. #include <Xm/PushBG.h>
  70. #include <Xm/SeparatoG.h>
  71. #include <Xm/ToggleBG.h>
  72. #include <Xm/CascadeBG.h>
  73. #include <Xm/Form.h>
  74. #include <Xm/Label.h>
  75. #define CHARSET XmSTRING_DEFAULT_CHARSET
  76. #else USE_ATHENA
  77. #include <X11/Xaw/AsciiText.h>
  78. #include <X11/Xaw/Box.h>
  79. #include <X11/Xaw/Paned.h>
  80. #include <X11/Xaw/Form.h>
  81. #include <X11/Xaw/Command.h>
  82. #include <X11/Xaw/Toggle.h>
  83. #include <X11/Xaw/MenuButton.h>
  84. #include <X11/Xaw/SimpleMenu.h>
  85. #include <X11/Xaw/SmeLine.h>
  86. #include <X11/Xaw/SmeBSB.h>
  87. #include <X11/bitmaps/xlogo16>
  88. #include <X11/Xaw/Viewport.h>
  89. #endif USE_ATHENA
  90. #include "Pixmap.h"
  91. #include "Version.h"
  92. #define TOGGLE True
  93. #define BUTTON False
  94.  
  95.  
  96. static char *usage = "[-options ...]\n\
  97. \n\
  98. where options include:\n\
  99.      -size WIDTHxHEIGHT\n\
  100.      -squares dimension\n\
  101.      -grid, +grid\n\
  102.      -stippled\n\
  103.      -stipple pixmap\n\
  104.      -axes, +axes\n\
  105.      -proportional, +proportional\n\
  106.      -hl color\n\
  107.      -fr color\n\
  108.      -tr color\n\
  109.      -fn/-font fontname\n\
  110.      -filename filename\n\
  111.      -f filename\n\
  112.      -in filename\n\
  113. \n\
  114. The default WIDTHxHEIGHT is 32x32.\n";
  115.  
  116.  
  117. static XrmOptionDescRec options[] = {
  118.   { "-squares",      "*pixmap.squareSize",     XrmoptionSepArg, NULL},
  119.   { "-grid",         "*pixmap.grid",           XrmoptionNoArg,  "False"},
  120.   { "+grid",         "*pixmap.grid",           XrmoptionNoArg,  "True"},
  121.   { "-stippled",     "*pixmap.stippled",       XrmoptionNoArg,  "False"},
  122.   { "-stipple",      "*pixmap.pixmap*stipple", XrmoptionSepArg, NULL},
  123.   { "-axes",         "*pixmap.axes",           XrmoptionNoArg,  "False"},
  124.   { "+axes",         "*pixmap.axes",           XrmoptionNoArg,  "True"},
  125.   { "-proportional", "*pixmap.proportional",   XrmoptionNoArg,  "False"},
  126.   { "+proportional", "*pixmap.proportional",   XrmoptionNoArg,  "True"},
  127.   { "-hl",           "*pixmap.highlight",      XrmoptionSepArg, NULL},
  128.   { "-fr",           "*pixmap.framing",        XrmoptionSepArg, NULL},
  129.   { "-tr",           "*pixmap.transparent",    XrmoptionSepArg, NULL},
  130.   { "-fn",           "*font",                  XrmoptionSepArg, "fixed"},
  131.   { "-font",         "*font",                  XrmoptionSepArg, "fixed"},
  132.   { "-filename",     "*pixmap.filename",       XrmoptionSepArg, NULL},
  133.   { "-f",            "*pixmap.filename",       XrmoptionSepArg, NULL},
  134.   { "-in",           "*pixmap.filename",       XrmoptionSepArg, NULL},
  135. };
  136.  
  137. /* Color is the maximal id usable for menu entries different from color */
  138. #define Color 200
  139. #define Color_offset Color
  140.  
  141. typedef struct {
  142.   int             id;
  143.   String          name;
  144.   Boolean         trap;
  145.   Widget          widget;
  146.   } ButtonRec;
  147.  
  148. static ButtonRec file_menu[] = {
  149. #define Load 26
  150.   {Load, "load", BUTTON},
  151. #define Insert 101
  152.   {Insert, "insert", BUTTON},
  153. #define Save 27
  154.   {Save, "save", BUTTON},
  155. #define SaveAs 28
  156.   {SaveAs, "saveAs", BUTTON},
  157. #define Dummy -1
  158.   {Dummy, "line", False},
  159. #define Resize 24
  160.   {Resize, "resize", BUTTON},
  161. #define Rescale 79
  162.   {Rescale, "rescale", BUTTON},
  163. #define Filename 74
  164.   {Filename, "filename", BUTTON},
  165. #define Hints 106
  166.   {Hints, "hintsCmt", BUTTON},
  167. #define Colors 107
  168.   {Colors, "colorsCmt", BUTTON},
  169. #define Pixels 108
  170.   {Pixels, "pixelsCmt", BUTTON},    
  171.   {Dummy, "line", False},
  172. #define Quit 75
  173.   {Quit, "quit", BUTTON},
  174. };
  175.  
  176. static ButtonRec edit_menu[] = {
  177. #define Image 77
  178.   {Image, "image", TOGGLE},
  179.   {Dummy, "line", False},
  180. #define Grid 23
  181.   {Grid, "grid", TOGGLE},
  182. #define Axes 34
  183.   {Axes, "axes", TOGGLE},
  184. #define Proportional 97
  185.   {Proportional, "proportional", TOGGLE},
  186. #define Zoom 100
  187.   {Zoom, "zoom", TOGGLE},
  188. #define ZoomIn 115
  189.   {ZoomIn, "zoomIn", BUTTON},
  190. #define ZoomOut 116
  191.   {ZoomOut, "zoomOut", BUTTON},
  192. #define ZoomFactor 117
  193.   {ZoomFactor, "zoomFactor", BUTTON},
  194. /* Dummy */
  195.   {Dummy, "line", False},
  196. #define Cut 30
  197.   {Cut, "cut", BUTTON},
  198. #define Copy 31
  199.   {Copy, "copy", BUTTON},
  200. #define Paste 4
  201.   {Paste, "paste", BUTTON},
  202. #define Crop 118
  203.   {Crop, "crop", BUTTON},
  204. };
  205.  
  206. static ButtonRec color_menu[] = {
  207. #define ColorPixel 109
  208.   {ColorPixel, "addColor", BUTTON},
  209. #define ColorSname 110
  210.   {ColorSname, "symbolicName", BUTTON},
  211. #define ColorMname 111
  212.   {ColorMname, "monochromeName", BUTTON},
  213. #define ColorG4name 112
  214.   {ColorG4name, "g4Name", BUTTON},
  215. #define ColorGname 113
  216.   {ColorGname, "gName", BUTTON},
  217. #define ColorCname 114
  218.   {ColorCname, "cName", BUTTON},
  219. };
  220.  
  221.  
  222. static ButtonRec extension_menu[] = {
  223.  
  224. #define AddExtension        119
  225.  
  226.   /* id,               name,               trap,   widget */
  227.   { AddExtension,     "addExtension",      BUTTON, NULL },
  228.   { Dummy,            "line",              False,  NULL },
  229. };
  230.  
  231.  
  232. static ButtonRec buttons[] = {
  233. #define Undo 25
  234.   {Undo, "undo", BUTTON},
  235. /*#define Clear 1*/
  236.   {Clear, "clear", BUTTON},
  237. /*#define Set 2*/
  238.   {Set, "set", BUTTON},
  239. #define Redraw 5
  240.   {Redraw, "redraw", BUTTON},
  241. #define CopyImm 102
  242.   {CopyImm, "copy", TOGGLE},
  243. #define MoveImm 103
  244.   {MoveImm, "move", TOGGLE},
  245. #define MarkImm 104
  246.   {MarkImm, "mark", TOGGLE},
  247. #define UnmarkImm 105
  248.   {UnmarkImm, "unmark", BUTTON},
  249. #define FlipHoriz 11
  250.   {FlipHoriz, "flipHoriz", BUTTON},
  251. #define Up 7
  252.   {Up, "up", BUTTON},
  253. #define FlipVert 12
  254.   {FlipVert, "flipVert", BUTTON},
  255. #define Left 9
  256.   {Left, "left", BUTTON},
  257. #define Fold 99
  258.   {Fold, "fold", BUTTON},
  259. #define Right 10
  260.   {Right, "right", BUTTON},
  261. #define RotateLeft 33
  262.   {RotateLeft, "rotateLeft", BUTTON},
  263. #define Down 8
  264.   {Down, "down", BUTTON},
  265. #define RotateRight 13
  266.   {RotateRight, "rotateRight", BUTTON},
  267. #define Point 14
  268.   {Point, "point", TOGGLE},
  269. #define Curve 41
  270.   {Curve, "curve", TOGGLE},
  271. #define Line 15
  272.   {Line, "line", TOGGLE},
  273. #define Rectangle 16
  274.   {Rectangle, "rectangle", TOGGLE},
  275. #define FilledRectangle 17
  276.   {FilledRectangle, "filledRectangle", TOGGLE},
  277. #define Circle 18
  278.   {Circle, "circle", TOGGLE},
  279. #define FilledCircle 19
  280.   {FilledCircle, "filledCircle", TOGGLE},
  281. #define FloodFill 20
  282.   {FloodFill, "floodFill", TOGGLE},
  283. #define Text 29
  284.   {Text, "text", TOGGLE},
  285. #define SetHotSpot 21
  286.   {SetHotSpot, "setHotSpot", TOGGLE},
  287. #define ClearHotSpot 22
  288.   {ClearHotSpot, "clearHotSpot", BUTTON},
  289. };
  290.  
  291. #include "Dialog.h"
  292.  
  293.  
  294. XtAppContext pixmap_context;
  295. Widget 
  296.     top_widget, 
  297.     parent_widget,
  298.     formy_widget,
  299.     infoButton_widget,
  300.     fileButton_widget, fileMenu_widget,
  301.     editButton_widget, editMenu_widget,
  302.     colorButton_widget, colorMenu_widget,
  303.     extensionMenu_widget,
  304.     extensionEditor, 
  305.     status_widget, statusb_widget,
  306.     pane_widget, color_pane_widget,
  307.     form_widget,
  308.     pixmap_widget,
  309.     image_shell,
  310.     image_widget;
  311.  
  312. #include "TextOptions.h"
  313. TextOptions *textOptions;
  314. #include "TextOptions.c"
  315.  
  316. Display *dpy;
  317. int screen;
  318. int ncolors;
  319. Pixel current_color;
  320. Colormap cmap;
  321.  
  322. /* picked up from rgb.c of Xpm lib */
  323. #ifndef UNUSE_XPM
  324. typedef struct {  /* rgb values and ascii names (from rgb text file) */
  325.    int  r, g, b;  /* rgb values, range of 0 -> 65535 */
  326.    char *name;    /* color mnemonic of rgb value */
  327. } RgbName;
  328. #define MAX_RGBNAMES 1024
  329. #endif UNUSE_XPM
  330. RgbName rgb_table[MAX_RGBNAMES];
  331.  
  332. int max_ncolors;
  333. char *colorInMenu;
  334. char *hints_cmt, *colors_cmt, *pixels_cmt;
  335. PWColorInfo **colorTable;
  336.  
  337. Boolean image_visible = False;
  338. Pixmap check_mark;
  339. Dialog info_dialog, input_dialog, error_dialog, qsave_dialog, file_dialog;
  340. String filename = NULL, format = "";
  341. char message[80];
  342.  
  343. extern int xpmReadRgbNames();
  344. extern char *xpmGetRgbName();
  345.  
  346. void FixMenu(), SwitchImage(), SwitchGrid(), SwitchAxes(), 
  347.   SwitchProportional(),   SwitchZoom(), DoLoad(), DoInsert(), DoSave(), 
  348.   DoSaveAs(), DoResize(), DoRescale(), DoFilename(), DoHintsCmt(), 
  349.   DoColorsCmt(), DoPixelsCmt(), DoQuit(), DoAddColor(), DoSymbolicName(), 
  350.   DoMonochromeName(), DoGrey4Name(), DoGreyName(), DoColorName(), DoCut(), 
  351.   DoCopy(), DoPaste(), DoCrop(), DoZoomIn(), DoZoomOut(), DoZoomFactor();
  352.  
  353. void TheCallback();
  354. void MakeMenuPanel();
  355.  
  356. static XtActionsRec actions_table[] = {
  357.   {"fix-menu", FixMenu},
  358.   {"switch-image", SwitchImage},
  359.   {"switch-grid", SwitchGrid},
  360.   {"switch-axes", SwitchAxes},
  361.   {"switch-proportional", SwitchProportional},
  362.   {"switch-zoom", SwitchZoom},
  363.   {"zoom-in", DoZoomIn},
  364.   {"zoom-out", DoZoomOut},
  365.   {"zoom-factor", DoZoomFactor},
  366.   {"do-load", DoLoad},
  367.   {"do-insert", DoInsert},
  368.   {"do-save", DoSave},
  369.   {"do-save-as", DoSaveAs},
  370.   {"do-resize", DoResize},
  371.   {"do-rescale", DoRescale},
  372.   {"do-filename", DoFilename},
  373.   {"do-hintscmt", DoHintsCmt},
  374.   {"do-colorscmt", DoColorsCmt},
  375.   {"do-pixelscmt", DoPixelsCmt},
  376.   {"do-quit", DoQuit},
  377.   {"do-addcolor", DoAddColor},
  378.   {"do-symbname", DoSymbolicName},
  379.   {"do-mononame", DoMonochromeName},
  380.   {"do-grey4name", DoGrey4Name},
  381.   {"do-greyname", DoGreyName},
  382.   {"do-colorname", DoColorName},
  383.   {"do-cut", DoCut},
  384.   {"do-copy", DoCopy},
  385.   {"do-paste", DoPaste},
  386.   {"do-crop", DoCrop}
  387. };
  388.  
  389. static Atom protocols[2];
  390.  
  391. void client_message(w, tag, event, b)
  392.      Widget w;
  393.      XtPointer tag;
  394.      XEvent *event;
  395.      Boolean *b;
  396. {
  397.   if (event->xclient.message_type == protocols[1] &&
  398.       event->xclient.data.l[0] == protocols[0])
  399.     /* the widget got a kill signal */
  400.     {
  401.       if (w == image_shell) 
  402.     SwitchImage();
  403.     }
  404. }
  405.  
  406. void unsetKillfromWM(w)
  407.      Widget w;
  408. {
  409.   
  410.   /* set WM property to receive a window deletion and avoid getting killed */
  411.   protocols[0] = XInternAtom(dpy, "WM_DELETE_WINDOW", True);
  412.   protocols[1] = XInternAtom(dpy, "WM_PROTOCOLS", True);
  413.   XSetWMProtocols(dpy, XtWindow(w), protocols, 1);
  414.   /* add handler to get WM's client message */
  415.   XtAddEventHandler(w, ClientMessage, True, 
  416.             (XtEventHandler)client_message, NULL);
  417. }
  418.  
  419.  
  420. FixColorMenuLabel(old_name, name)
  421.      char *old_name;
  422.      char *name;
  423. {
  424.   Widget colorButton;
  425.   Arg wargs[1];
  426. #ifndef USE_ATHENA
  427.   XmString xmstr;
  428.  
  429.   xmstr = XmStringCreateLtoR(name, CHARSET);
  430.   XtSetArg(wargs[0], XmNlabelString, xmstr);
  431. #else USE_ATHENA
  432.   XtSetArg(wargs[0], XtNlabel, name);
  433. #endif
  434.  
  435.   colorButton = XtNameToWidget( formy_widget, "colorButton" );
  436.   XtSetValues( colorButton, wargs, 1 );
  437.  
  438. #ifndef USE_ATHENA
  439.   XmStringFree(xmstr);
  440. #endif
  441. }
  442.  
  443.  
  444. AddColorNotifyProc colorToAdd(w, pixel, name)
  445.      Widget w;
  446.      Pixel pixel;
  447.      char *name;
  448. {
  449.   Widget wi;
  450.   int max_colors = 1<<DisplayPlanes(dpy,screen);
  451.   /* index is 0 for transparent and pixel+1 for other colors */
  452.   int index = (pixel == TRANSPARENT(dpy, screen) ? 0 : pixel + 1);
  453.   
  454.   if ((pixel != TRANSPARENT(dpy, screen)) &&
  455.       ((pixel < 0) || (pixel >= max_colors)))
  456.     printf(
  457.     "Warning: Color pixel %d out of bounds for display (pixel range [0->%d]\n",
  458.        pixel, max_colors-1);
  459.   else if (colorInMenu[index] == 0)
  460.     {
  461.       int *id = (int *)XtMalloc(sizeof(int));
  462.       char *menu_name;
  463.       XColor color;
  464.       Arg wargs[1];
  465.       Boolean no_name = False;
  466.  
  467.       *id = pixel + Color_offset;
  468.       colorInMenu[index] = '1';
  469.  
  470.       /* Two kinds of colors: not transparent and transparent */
  471.       if (pixel != TRANSPARENT(dpy, screen))
  472.       {
  473.       color.pixel = pixel;
  474.       XQueryColor(dpy, DefaultColormap(dpy, screen), &color);
  475.       
  476. #ifndef USE_ATHENA
  477.       XtSetArg(wargs[0], XmNbackground, pixel);
  478. #else USE_ATHENA
  479.       XtSetArg(wargs[0], XtNbackground, pixel);
  480. #endif
  481.       
  482.       if (!name)
  483.       {
  484.           if (!(menu_name = xpmGetRgbName(rgb_table, max_ncolors,
  485.                           (int) color.red,
  486.                           (int) color.green,
  487.                           (int)color.blue)))
  488.           {
  489.           no_name = True;
  490.           menu_name = (char *) XtMalloc(15*sizeof(char));
  491.           sprintf(menu_name, "#%04X%04X%04X", 
  492.               color.red, color.green, color.blue);
  493.           }
  494.       }
  495.       else menu_name = name;
  496.       
  497. #ifdef DEBUG
  498.       printf("Adding color %d %s to menu\n", pixel, name);
  499. #endif DEBUG
  500.       
  501.       if ((color.red != 0) || (color.green != 0) || (color.blue != 0) ||
  502.           (color.pixel == BlackPixel(dpy, screen)))
  503.       {
  504. #ifndef USE_ATHENA
  505.           wi = (Widget)XmCreatePushButton(color_pane_widget, menu_name,
  506.                           wargs, 1);
  507.           XtAddCallback(wi, XmNactivateCallback, TheCallback, id);
  508.           XtManageChild(wi);
  509. #else USE_ATHENA
  510.           wi = XtCreateManagedWidget(menu_name, commandWidgetClass, 
  511.                      color_pane_widget, wargs, 1);
  512.           XtAddCallback(wi, XtNcallback, TheCallback, id);
  513. #endif
  514.       }
  515.       
  516.       if (no_name) XtFree(menu_name);
  517.       }
  518.       else if (pixel == TRANSPARENT(dpy, screen))
  519.       {
  520. #ifndef USE_ATHENA
  521.       XtSetArg(wargs[0], XmNbackground,
  522.            PWGetTransparentPixel(w));
  523.       wi = (Widget)XmCreatePushButton(color_pane_widget, name,
  524.                       wargs, 1);
  525.       XtAddCallback(wi, XmNactivateCallback, TheCallback, id);
  526.       XtManageChild(wi);
  527. #else USE_ATHENA
  528.       XtSetArg(wargs[0], XtNbackground,
  529.            PWGetTransparentPixel(w));
  530.       wi = XtCreateManagedWidget(name, commandWidgetClass, 
  531.                      color_pane_widget, wargs, 1);
  532.       XtAddCallback(wi, XtNcallback, TheCallback, id);
  533. #endif
  534.       }
  535.   }
  536. #ifdef DEBUG
  537.   else printf("Already used color!\n");
  538. #endif DEBUG
  539. }
  540.  
  541.  
  542. void FixImage(w, client_data, call_data)
  543.      Widget w;
  544.      XtPointer client_data, call_data;
  545. {
  546.     Pixmap image, image_mask;
  547.     Window root;
  548.     unsigned int width, height, border_width, depth;
  549.     int x, y;
  550.  
  551.     if (!image_visible)
  552.       {
  553. #ifndef USE_ATHENA
  554.     XmToggleButtonGadgetSetState(edit_menu[0].widget, False, False);
  555. #endif
  556.     return;
  557.       }
  558. #ifndef USE_ATHENA
  559.     else XmToggleButtonGadgetSetState(edit_menu[0].widget, True, False);
  560. #endif
  561.     
  562.     PWGetUnzoomedPixmap(pixmap_widget, &image, &image_mask);
  563.     XGetGeometry(XtDisplay(image_widget), image, &root, &x, &y, 
  564.          &width, &height, &border_width, &depth);
  565.     XResizeWindow(XtDisplay(image_widget), XtWindow(image_shell), 
  566.           width, height);
  567.     
  568.     XSetWindowBackgroundPixmap(XtDisplay(pixmap_widget), 
  569.                    XtWindow(image_widget), image); 
  570.  
  571.     if (image_mask) 
  572.       {
  573.     XShapeCombineMask(XtDisplay(image_widget), 
  574.               XtWindow(image_widget), ShapeBounding,
  575.               0, 0, image_mask, ShapeSet);
  576.     XShapeCombineMask(XtDisplay(pixmap_widget), 
  577.               XtWindow(image_shell), ShapeBounding,
  578.               0, 0, image_mask, ShapeSet);
  579.       }
  580.     else 
  581.       {
  582.     XShapeCombineMask(XtDisplay(image_widget), 
  583.               XtWindow(image_widget), ShapeBounding,
  584.               0, 0, None, ShapeSet);
  585.     XShapeCombineMask(XtDisplay(pixmap_widget), 
  586.               XtWindow(image_shell), ShapeBounding,
  587.               0, 0, None, ShapeSet);
  588.       }
  589.  
  590.     XClearWindow(XtDisplay(pixmap_widget), XtWindow(image_widget));
  591.     XFreePixmap(XtDisplay(pixmap_widget), image);
  592.     if (image_mask) XFreePixmap(XtDisplay(image_widget), image_mask);
  593. }
  594.  
  595. void FixEntry(w, id)
  596.     Widget w;
  597.     int *id;
  598. {
  599.     int n;
  600.     Arg wargs[2];
  601.  
  602.  
  603.     n = 0;
  604.     switch (*id) {
  605.     
  606.     case Image:
  607. #ifndef USE_ATHENA
  608.         XtSetArg(wargs[n], XmNset, image_visible); n++;
  609. #else USE_ATHENA
  610.     XtSetArg(wargs[n], XtNleftBitmap, 
  611.          image_visible ? check_mark : None); n++;
  612. #endif 
  613.     break;
  614.     
  615.     case Grid:
  616. #ifndef USE_ATHENA
  617.         XtSetArg(wargs[n], XmNset, PWQueryGrid(pixmap_widget)); n++;
  618. #else USE_ATHENA
  619.     XtSetArg(wargs[n], XtNleftBitmap, 
  620.          PWQueryGrid(pixmap_widget) ? check_mark : None); n++;
  621. #endif
  622.     break;
  623.  
  624.     case Axes:
  625. #ifndef USE_ATHENA
  626.         XtSetArg(wargs[n], XmNset, PWQueryAxes(pixmap_widget)); n++;
  627. #else USE_ATHENA
  628.     XtSetArg(wargs[n], XtNleftBitmap, 
  629.          PWQueryAxes(pixmap_widget) ? check_mark : None); n++;
  630. #endif
  631.     break;
  632.     
  633.     case Proportional:
  634. #ifndef USE_ATHENA
  635.         XtSetArg(wargs[n], XmNset, PWQueryProportional(pixmap_widget)); n++;
  636. #else USE_ATHENA
  637.     XtSetArg(wargs[n], XtNleftBitmap, 
  638.          PWQueryProportional(pixmap_widget) ? check_mark : None); n++;
  639. #endif
  640.     break;
  641.     
  642.     case Zoom:
  643. #ifndef USE_ATHENA
  644.         XtSetArg(wargs[n], XmNset, PWQueryZooming(pixmap_widget)); n++;
  645. #else USE_ATHENA
  646.     XtSetArg(wargs[n], XtNleftBitmap, 
  647.          PWQueryZooming(pixmap_widget) ? check_mark : None); n++;
  648. #endif
  649.     break;
  650.  
  651.     case Copy:
  652.     case Cut:
  653. #ifndef USE_ATHENA
  654.     XtSetArg(wargs[n], XmNsensitive, PWQueryMarked(pixmap_widget)); n++;
  655. #else USE_ATHENA
  656.     XtSetArg(wargs[n], XtNsensitive, PWQueryMarked(pixmap_widget)); n++;
  657. #endif
  658.     break;
  659.  
  660.     case Paste:
  661. #ifndef USE_ATHENA
  662.     XtSetArg(wargs[n], XmNsensitive, PWQueryStored(pixmap_widget)); n++;
  663. #else USE_ATHENA
  664.     XtSetArg(wargs[n], XtNsensitive, PWQueryStored(pixmap_widget)); n++;
  665. #endif
  666.     break;
  667.  
  668.     case Crop:
  669. #ifndef USE_ATHENA
  670.     XtSetArg(wargs[n], XmNsensitive,
  671.          PWQueryMarked(pixmap_widget) || PWQueryStored(pixmap_widget));
  672.     n++;
  673. #else USE_ATHENA
  674.     XtSetArg(wargs[n], XtNsensitive,
  675.          PWQueryMarked(pixmap_widget) || PWQueryStored(pixmap_widget));
  676.     n++;
  677. #endif
  678.     break;
  679.  
  680.     default:
  681.     return;
  682.     }
  683.     
  684.     XtSetValues(w, wargs, n);
  685. }
  686.  
  687. void FixMenu(w, event)
  688.     Widget w;
  689.     XEvent *event;
  690. {
  691.     int i;
  692.  
  693.     for (i = 0; i < XtNumber(edit_menu); i++)
  694.     FixEntry(edit_menu[i].widget, &edit_menu[i].id);
  695. }
  696.  
  697. FixStatus()
  698. {
  699.     int n;
  700.     Arg wargs[2];
  701.     String str;
  702.     char fname[256], *fn = fname;
  703.     char size[50];
  704. #ifndef USE_ATHENA
  705.     XmString xmstr;
  706. #endif
  707.  
  708.     str = PWUnparseStatus(pixmap_widget);
  709.  
  710.     n = 0;
  711. #ifndef USE_ATHENA
  712.     while ((*str != ' ') || (*(str-1) == ':')) *fn++ = *str++;
  713.     *fn = 0;
  714.     strcpy(size, str);
  715.     xmstr = XmStringCreateLtoR(fname, XmSTRING_DEFAULT_CHARSET);
  716.     XtSetArg(wargs[n], XmNlabelString, xmstr); n++;
  717.     XtSetValues(status_widget, wargs, n);
  718.     XmStringFree(xmstr);
  719.     xmstr = XmStringCreateLtoR(size, XmSTRING_DEFAULT_CHARSET);
  720.     XtSetArg(wargs[n], XmNlabelString, xmstr); n++;
  721.     XtSetValues(statusb_widget, wargs, n);
  722.     XmStringFree(xmstr);
  723. #else USE_ATHENA
  724.     XtSetArg(wargs[n], XtNlabel, str); n++;
  725.     XtSetValues(status_widget, wargs, n);
  726. #endif
  727. }
  728.  
  729. UseColorNotifyProc FixColor(w, current)
  730.      Widget w;
  731.      Pixel current;
  732. {
  733.   Widget colorButton;
  734.   Arg wargs[1];
  735.   /* index in colorTable is 0 for transparent, pixel+1 for other colors */
  736.   int index = (current == TRANSPARENT(dpy, screen) ? 0 : current + 1);
  737. #ifndef USE_ATHENA
  738.   XmString xmstr;
  739. #endif
  740.  
  741.   current_color = current;
  742.   colorTable = PWGetColorTable(w);
  743.  
  744. #ifndef USE_ATHENA
  745.   xmstr = XmStringCreateLtoR(colorTable[index]->c_name, CHARSET);
  746.   XtSetArg(wargs[0], XmNlabelString, xmstr);
  747. #else USE_ATHENA  
  748.   XtSetArg(wargs[0], XtNlabel, colorTable[index]->c_name);
  749. #endif
  750.  
  751.   colorButton = XtNameToWidget( formy_widget, "colorButton" );
  752.   XtSetValues( colorButton, wargs, 1 );
  753. #ifndef USE_ATHENA
  754.   XmStringFree(xmstr);
  755. #endif
  756. }
  757.  
  758. static int zero = 0;
  759. #define Plain  (XtPointer)&zero,(Cardinal)sizeof(int)
  760.  
  761. void TheCallback(w, client_data, call_data)
  762.      Widget w;
  763.      XtPointer client_data, call_data;
  764. {
  765.     int   *id = (int *)client_data;
  766.     
  767.     switch (*id) {
  768.       
  769.     case Load:
  770.       DoLoad();
  771.       break;
  772.       
  773.     case Insert:
  774.       DoInsert();
  775.       break;
  776.       
  777.     case Save:
  778.       DoSave();
  779.       break;
  780.       
  781.     case SaveAs:
  782.       DoSaveAs();
  783.       break;
  784.       
  785.     case Filename:
  786.       DoFilename();
  787.       break;
  788.       
  789.     case Hints:
  790.       DoHintsCmt();
  791.       break;
  792.     case Colors:
  793.       DoColorsCmt();
  794.       break;
  795.     case Pixels:
  796.       DoPixelsCmt();
  797.       break;
  798.       
  799.     case Quit:
  800.       DoQuit();
  801.       break;
  802.       
  803.     case ColorPixel:
  804.       DoAddColor();
  805.       break;
  806.     case ColorSname:
  807.       DoSymbolicName();
  808.       break;
  809.     case ColorMname:
  810.       DoMonochromeName();
  811.       break;
  812.     case ColorG4name:
  813.       DoGrey4Name();
  814.       break;
  815.     case ColorGname:
  816.       DoGreyName();
  817.       break;
  818.     case ColorCname:
  819.       DoColorName();
  820.       break;
  821.       
  822.     case Image:
  823.       SwitchImage();
  824.       break;
  825.       
  826.     case Grid:
  827.       SwitchGrid();
  828.       break;
  829.       
  830.     case Axes:
  831.       SwitchAxes();
  832.       break;    
  833.       
  834.     case Proportional:
  835.       SwitchProportional();
  836.       break;
  837.       
  838.     case Zoom:
  839.       SwitchZoom();
  840.       break;
  841.  
  842.     case ZoomIn:
  843.       DoZoomIn();
  844.       break;
  845.       
  846.     case ZoomOut:
  847.       DoZoomOut();
  848.       break;
  849.       
  850.     case ZoomFactor:
  851.       DoZoomFactor();
  852.       break;
  853.  
  854.     case Resize:
  855.       DoResize();
  856.       break;
  857.       
  858.     case Rescale:
  859.       DoRescale();
  860.       break;
  861.  
  862.     case Copy:
  863.       DoCopy();
  864.       break;
  865.       
  866.     case Cut:
  867.       DoCut();
  868.       break;
  869.       
  870.     case Paste:
  871.       DoPaste();
  872.       break;
  873.       
  874.     case Crop:
  875.       DoCrop();
  876.       break;
  877.       
  878.     case Clear:
  879.       PWStoreToBuffer(pixmap_widget);
  880.       PWClear(pixmap_widget);
  881.       PWChangeNotify(pixmap_widget, NULL, NULL);
  882.       PWSetChanged(pixmap_widget);
  883.       break;
  884.       
  885.     case Set:
  886.       PWStoreToBuffer(pixmap_widget);
  887.       PWSet(pixmap_widget);
  888.       PWChangeNotify(pixmap_widget, NULL, NULL);
  889.       PWSetChanged(pixmap_widget);
  890.       break;
  891.       
  892.     case Redraw:
  893.       PWRedraw(pixmap_widget);
  894.       FixImage(pixmap_widget, NULL, NULL);
  895.       break;
  896.       
  897.     case CopyImm:
  898.       PWRemoveAllRequests(pixmap_widget);
  899.       if (PWQueryMarked(pixmap_widget)) {
  900.     PWAddRequest(pixmap_widget, MarkRequest, False, Plain);
  901.     PWEngageRequest(pixmap_widget, CopyRequest, True, Plain);
  902.       }
  903.       else {
  904.     PWEngageRequest(pixmap_widget, MarkRequest, False, Plain);
  905.     PWAddRequest(pixmap_widget, CopyRequest, True, Plain);
  906.       }
  907.       break;
  908.       
  909.     case MoveImm:
  910.       PWRemoveAllRequests(pixmap_widget);
  911.       if (PWQueryMarked(pixmap_widget)) {
  912.     PWAddRequest(pixmap_widget, MarkRequest, False, Plain);
  913.     PWEngageRequest(pixmap_widget, MoveRequest, True, Plain);
  914.       }
  915.       else {
  916.     PWEngageRequest(pixmap_widget, MarkRequest, False, Plain);
  917.     PWAddRequest(pixmap_widget, MoveRequest, True, Plain);
  918.       }
  919.       break;
  920.       
  921.     case MarkImm:
  922.       PWRemoveAllRequests(pixmap_widget);
  923.       PWEngageRequest(pixmap_widget, MarkRequest, True, Plain);
  924.       break;
  925.       
  926.     case UnmarkImm:
  927.       PWUnmark((Widget)pixmap_widget);
  928.       break;
  929.       
  930.     case Up:
  931.       PWStoreToBuffer(pixmap_widget);
  932.       PWUp(pixmap_widget);
  933.       PWChangeNotify(pixmap_widget, NULL, NULL);
  934.       PWSetChanged(pixmap_widget);
  935.       break;
  936.       
  937.     case Down:
  938.       PWStoreToBuffer(pixmap_widget);
  939.       PWDown(pixmap_widget);
  940.       PWChangeNotify(pixmap_widget, NULL, NULL);
  941.       PWSetChanged(pixmap_widget);
  942.       break;
  943.       
  944.     case Left:
  945.       PWStoreToBuffer(pixmap_widget);
  946.       PWLeft(pixmap_widget);
  947.       PWChangeNotify(pixmap_widget, NULL, NULL);
  948.       PWSetChanged(pixmap_widget);
  949.       break;
  950.       
  951.     case Right:
  952.       PWStoreToBuffer(pixmap_widget);
  953.       PWRight(pixmap_widget);
  954.       PWChangeNotify(pixmap_widget, NULL, NULL);
  955.       PWSetChanged(pixmap_widget);
  956.       break;
  957.       
  958.     case Fold:
  959.       PWStoreToBuffer(pixmap_widget);
  960.       PWFold(pixmap_widget);
  961.       PWChangeNotify(pixmap_widget, NULL, NULL);
  962.       PWSetChanged(pixmap_widget);
  963.       break;
  964.       
  965.     case FlipHoriz:
  966.       PWStoreToBuffer(pixmap_widget);
  967.       PWFlipHoriz(pixmap_widget);
  968.       PWChangeNotify(pixmap_widget, NULL, NULL);
  969.       PWSetChanged(pixmap_widget);
  970.       break;
  971.       
  972.     case FlipVert:
  973.       PWStoreToBuffer(pixmap_widget);
  974.       PWFlipVert(pixmap_widget);
  975.       PWChangeNotify(pixmap_widget, NULL, NULL);
  976.       PWSetChanged(pixmap_widget);
  977.       break;
  978.       
  979.     case RotateRight:
  980.       PWStoreToBuffer(pixmap_widget);
  981.       PWRotateRight(pixmap_widget);
  982.       PWChangeNotify(pixmap_widget, NULL, NULL);
  983.       PWSetChanged(pixmap_widget);
  984.       break;
  985.       
  986.     case RotateLeft:
  987.       PWStoreToBuffer(pixmap_widget);
  988.       PWRotateLeft(pixmap_widget);
  989.       PWChangeNotify(pixmap_widget, NULL, NULL);
  990.       PWSetChanged(pixmap_widget);
  991.       break;
  992.       
  993.     case Point:
  994.       PWRemoveAllRequests(pixmap_widget);
  995.       PWEngageRequest(pixmap_widget, PointRequest, True, Plain);
  996.       break;
  997.       
  998.     case Curve:
  999.       PWRemoveAllRequests(pixmap_widget);
  1000.       PWEngageRequest(pixmap_widget, CurveRequest, True, Plain);
  1001.       break;
  1002.       
  1003.     case Line:
  1004.       PWRemoveAllRequests(pixmap_widget);
  1005.       PWEngageRequest(pixmap_widget, LineRequest, True, Plain);
  1006.       break;
  1007.       
  1008.     case Rectangle:
  1009.       PWRemoveAllRequests(pixmap_widget);
  1010.       PWEngageRequest(pixmap_widget, RectangleRequest, True, Plain);
  1011.       break;
  1012.       
  1013.     case FilledRectangle:
  1014.       PWRemoveAllRequests(pixmap_widget);
  1015.       PWEngageRequest(pixmap_widget, FilledRectangleRequest, True, Plain);
  1016.       break;
  1017.       
  1018.     case Circle:
  1019.       PWRemoveAllRequests(pixmap_widget);
  1020.       PWEngageRequest(pixmap_widget, CircleRequest, True, Plain);
  1021.       break;
  1022.       
  1023.     case FilledCircle:
  1024.       PWRemoveAllRequests(pixmap_widget);
  1025.       PWEngageRequest(pixmap_widget, FilledCircleRequest, True, Plain);
  1026.       break;
  1027.       
  1028.     case FloodFill:
  1029.       PWRemoveAllRequests(pixmap_widget);
  1030.       PWEngageRequest(pixmap_widget, FloodFillRequest, True, Plain);
  1031.       break;
  1032.       
  1033.     case Text:
  1034.       PopupTextOptions( w, textOptions );
  1035.       PWRemoveAllRequests(pixmap_widget);
  1036.       PWEngageRequest(pixmap_widget, TextRequest, True, Plain);
  1037.       break;
  1038.       
  1039.     case SetHotSpot:
  1040.     PWRemoveAllRequests(pixmap_widget);
  1041.     PWEngageRequest(pixmap_widget, HotSpotRequest, True, Plain);
  1042.     break;
  1043.     
  1044.     case ClearHotSpot:
  1045.     PWStoreToBuffer(pixmap_widget);
  1046.     PWClearHotSpot(pixmap_widget);
  1047.     PWChangeNotify(pixmap_widget, NULL, NULL);
  1048.     PWSetChanged(pixmap_widget);
  1049.     break;
  1050.  
  1051.     case Undo:
  1052.       PWUndo(pixmap_widget);
  1053. #ifdef USE_ATHENA
  1054.       PWRedraw(pixmap_widget);
  1055. #endif
  1056.       PWChangeNotify(pixmap_widget, NULL, NULL);
  1057.       PWSetChanged(pixmap_widget);
  1058.       FixStatus();
  1059.       break;    
  1060.     case Color: /* Start of colors management */
  1061.     default: /* Don't change this default section: color management */
  1062.       PWSetForeground(pixmap_widget,(*id - Color_offset));
  1063.       FixColor(pixmap_widget, *id - Color_offset);
  1064.       break; 
  1065.     }
  1066. }
  1067.  
  1068.  
  1069. void DoLoad()
  1070. {
  1071.   if (PWQueryChanged(pixmap_widget)) {
  1072.     PWGetFilename(pixmap_widget, &filename);
  1073.   RetryLoadSave:
  1074.     switch (PopupDialog(qsave_dialog, "Save file before loading?",
  1075.             filename, &filename, XtGrabExclusive)) {
  1076.     case Yes:
  1077.       if (PWWriteFile(pixmap_widget, filename) != XpmSuccess) {
  1078.     sprintf(message, "Can't write file: %s", filename);
  1079.     if (PopupDialog(error_dialog, message, 
  1080.             NULL, NULL, XtGrabExclusive) == Retry) 
  1081.       goto RetryLoadSave;
  1082.       }
  1083.       break;
  1084.       
  1085.     case Cancel:
  1086.       return;
  1087.     }
  1088.   }
  1089.   PWGetFilepath(pixmap_widget, &filename);
  1090.  RetryLoad:
  1091.   if (PopupDialog(file_dialog, "Load file:", 
  1092.           filename, &filename, XtGrabExclusive) == Okay) {
  1093.     if (PWReadFile(pixmap_widget, filename) != XpmSuccess) {
  1094.       sprintf(message, "Can't read file: %s", filename);
  1095.       if (PopupDialog(error_dialog, message, 
  1096.               NULL, NULL, XtGrabExclusive) == Retry)
  1097.     goto RetryLoad;
  1098.     }
  1099.     else {
  1100.       PWChangeNotify(pixmap_widget, NULL, NULL);
  1101.       PWClearChanged(pixmap_widget);
  1102.       FixStatus();
  1103.     }
  1104.   }
  1105. }
  1106.  
  1107. void DoInsert()
  1108. {
  1109.   PWGetFilepath(pixmap_widget, &filename);
  1110.  RetryInsert:
  1111.   if (PopupDialog(file_dialog, "Insert file:", 
  1112.           filename, &filename, XtGrabExclusive) == Okay) {
  1113.     if (PWStoreFile(pixmap_widget, filename) != XpmSuccess) {
  1114.       sprintf(message, "Can't read file: %s", filename);
  1115.       if (PopupDialog(error_dialog, message, 
  1116.               NULL, NULL, XtGrabExclusive) == Retry)
  1117.     goto RetryInsert;
  1118.     }
  1119.     else {
  1120.       PWEngageRequest(pixmap_widget, RestoreRequest, False, Plain);
  1121.     }
  1122.   }
  1123. }
  1124.  
  1125. void DoSave()
  1126. {
  1127.   PWGetFilename(pixmap_widget, &filename);
  1128.   if (PWWriteFile(pixmap_widget, filename) != XpmSuccess) 
  1129.     {
  1130.       sprintf(message, "Can't write file: %s", filename);
  1131.       if (PopupDialog(error_dialog, message, 
  1132.               NULL, NULL, XtGrabExclusive) == Retry) 
  1133.     DoSaveAs();
  1134.     }
  1135.   else {
  1136.     PWClearChanged(pixmap_widget);
  1137.   }
  1138. }
  1139.  
  1140. void DoSaveAs()
  1141. {
  1142.   PWGetFilename(pixmap_widget, &filename);
  1143.  RetrySave:
  1144.   if (PopupDialog(file_dialog, "Save file:", 
  1145.           filename, &filename, XtGrabExclusive) == Okay) {
  1146.     if (PWWriteFile(pixmap_widget, filename) != XpmSuccess) {
  1147.       sprintf(message, "Can't write file: %s", filename);
  1148.       if (PopupDialog(error_dialog, message, 
  1149.               NULL, NULL, XtGrabExclusive) == Retry)
  1150.     goto RetrySave;
  1151.     }
  1152.     else {
  1153.       PWClearChanged(pixmap_widget);
  1154.       FixStatus();
  1155.     }
  1156.   }
  1157. }
  1158.  
  1159. void DoFilename()
  1160. {
  1161.   PWGetFilename(pixmap_widget, &filename);
  1162.   if (PopupDialog(file_dialog, "Change filename:", 
  1163.           filename, &filename, XtGrabExclusive) == Okay) {
  1164.     PWChangeFilename(pixmap_widget, filename);
  1165.     FixStatus();
  1166.   }
  1167. }
  1168.  
  1169. void DoHintsCmt()
  1170. {
  1171.   PWComments(pixmap_widget, &hints_cmt, &colors_cmt, &pixels_cmt);
  1172.   if (PopupDialog(input_dialog, "Pixmap hints comment:", 
  1173.           (hints_cmt ? hints_cmt : ""), &hints_cmt, 
  1174.           XtGrabExclusive) == Okay)
  1175.     PWComments(pixmap_widget, &hints_cmt, &colors_cmt, &pixels_cmt);
  1176.   if (hints_cmt) XtFree(hints_cmt);
  1177.   if (colors_cmt) XtFree(colors_cmt);
  1178.   if (pixels_cmt) XtFree(pixels_cmt);
  1179.   hints_cmt = 0;
  1180.   colors_cmt = 0;
  1181.   pixels_cmt = 0;
  1182. }
  1183.  
  1184. void DoColorsCmt()
  1185. {
  1186.   PWComments(pixmap_widget, &hints_cmt, &colors_cmt, &pixels_cmt);
  1187.   if (PopupDialog(input_dialog, "Pixmap colors comment:", 
  1188.           (colors_cmt ? colors_cmt : ""), &colors_cmt, 
  1189.           XtGrabExclusive) == Okay)
  1190.     PWComments(pixmap_widget, &hints_cmt, &colors_cmt, &pixels_cmt);
  1191.   if (hints_cmt) XtFree(hints_cmt);
  1192.   if (colors_cmt) XtFree(colors_cmt);
  1193.   if (pixels_cmt) XtFree(pixels_cmt);
  1194.   hints_cmt = 0;
  1195.   colors_cmt = 0;
  1196.   pixels_cmt = 0;
  1197. }
  1198.  
  1199. void DoPixelsCmt()
  1200. {
  1201.   PWComments(pixmap_widget, &hints_cmt, &colors_cmt, &pixels_cmt);
  1202.   if (PopupDialog(input_dialog, "Pixmap pixels comment:", 
  1203.           (pixels_cmt ? pixels_cmt : ""), &pixels_cmt, 
  1204.           XtGrabExclusive) == Okay)
  1205.     PWComments(pixmap_widget, &hints_cmt, &colors_cmt, &pixels_cmt);
  1206.   if (hints_cmt) XtFree(hints_cmt);
  1207.   if (colors_cmt) XtFree(colors_cmt);
  1208.   if (pixels_cmt) XtFree(pixels_cmt);
  1209.   hints_cmt = 0;
  1210.   colors_cmt = 0;
  1211.   pixels_cmt = 0;
  1212. }
  1213.  
  1214. void DoQuit()
  1215. {
  1216.   if (PWQueryChanged(pixmap_widget)) {
  1217.     PWGetFilename(pixmap_widget, &filename);
  1218.   RetryQuit:
  1219.     switch (PopupDialog(qsave_dialog, "Save file before quitting?",
  1220.             filename, &filename, XtGrabExclusive)) {
  1221.     case Yes:
  1222.       if (PWWriteFile(pixmap_widget, filename) != XpmSuccess) {
  1223.     sprintf(message, "Can't write file: %s", filename);
  1224.     if (PopupDialog(error_dialog, message, 
  1225.             NULL, NULL, XtGrabExclusive) == Retry) 
  1226.       goto RetryQuit;
  1227.     else return;
  1228.       }
  1229.       break;
  1230.       
  1231.     case Cancel:
  1232.       return;
  1233.     }
  1234.   }
  1235.   exit(0);
  1236. }
  1237.  
  1238. void DoAddColor()
  1239. {
  1240.   char *cname;
  1241.   
  1242.   if (PopupDialog(input_dialog, "Color name (name or #rgb) to add:",
  1243.           "", &cname, XtGrabExclusive) == Okay)
  1244.     {
  1245.       XColor color;
  1246.       
  1247.       if ((!XParseColor(dpy, cmap, cname, &color)) ||
  1248.       (!XAllocColor(dpy, cmap, &color)))
  1249.     {
  1250.       fprintf(stderr, 
  1251.           "Warning: color %s could not be parsed/allocated!",
  1252.           cname);
  1253.     }
  1254.       else
  1255.     {
  1256.       colorToAdd(pixmap_widget, color.pixel, 
  1257.              ((cname[0] == '#') ? 
  1258.               xpmGetRgbName(rgb_table, max_ncolors, 
  1259.                     (int) color.red,
  1260.                     (int) color.green,
  1261.                     (int) color.blue) : cname));
  1262.       PWUseColorInTable(pixmap_widget, color.pixel, NULL, NULL, NULL,
  1263.                 NULL, NULL,
  1264.                 ((cname[0] == '#') ? 
  1265.                  xpmGetRgbName(rgb_table, max_ncolors, 
  1266.                        (int) color.red,
  1267.                        (int) color.green,
  1268.                        (int) color.blue) : cname));
  1269.     }
  1270.     }
  1271. }
  1272.  
  1273. void DoSymbolicName()
  1274. {
  1275.   char *s_name;
  1276.   char message[80];
  1277.   /* index in colorTable is 0 for transparent, pixel+1 for other colors */
  1278.   int index = (current_color == TRANSPARENT(dpy, screen) ? 0 : current_color + 1);
  1279.   
  1280.   colorTable = PWGetColorTable(pixmap_widget);
  1281.   sprintf(message, "Color `%s' [%d] symbolic name:", 
  1282.       colorTable[index]->c_name, current_color);
  1283.   
  1284.   if (PopupDialog(input_dialog, message, 
  1285.           (colorTable[index]->s_name ? 
  1286.            colorTable[index]->s_name : ""), 
  1287.           &s_name,
  1288.           XtGrabExclusive) == Okay)
  1289.     PWUpdateColorInTable(pixmap_widget, 
  1290.              current_color,
  1291.              colorTable[index]->symbol,
  1292.              s_name,
  1293.              colorTable[index]->m_name,
  1294.              colorTable[index]->g4_name,
  1295.              colorTable[index]->g_name,
  1296.              colorTable[index]->c_name);
  1297. }
  1298.  
  1299. void DoMonochromeName()
  1300. {
  1301.   char *m_name;
  1302.   char message[80];
  1303.   /* index in colorTable is 0 for transparent, pixel+1 for other colors */
  1304.   int index = (current_color == TRANSPARENT(dpy, screen) ? 0 : current_color + 1);
  1305.   
  1306.   colorTable = PWGetColorTable(pixmap_widget);
  1307.   sprintf(message, "Color `%s' [%d] monochrome display name:", 
  1308.       colorTable[index]->c_name, current_color);
  1309.   
  1310.   if (PopupDialog(input_dialog, message, 
  1311.           (colorTable[index]->m_name ? 
  1312.            colorTable[index]->m_name : ""), 
  1313.           &m_name,
  1314.           XtGrabExclusive) == Okay)
  1315.   {
  1316.       XColor color;
  1317.       
  1318.       if (!XParseColor(dpy, cmap, m_name, &color))
  1319.     {
  1320.       fprintf(stderr, "Warning: color %s could not be parsed!\n",
  1321.           m_name);
  1322.     }
  1323.       else
  1324.     PWUpdateColorInTable(pixmap_widget, 
  1325.                  current_color,
  1326.                  colorTable[index]->symbol,
  1327.                  colorTable[index]->s_name,
  1328.                  m_name,
  1329.                  colorTable[index]->g4_name,
  1330.                  colorTable[index]->g_name,
  1331.                  colorTable[index]->c_name);
  1332.   }
  1333. }
  1334.  
  1335. void DoGrey4Name()
  1336. {
  1337.   char *g4_name;
  1338.   char message[80];
  1339.   /* index in colorTable is 0 for transparent, pixel+1 for other colors */
  1340.   int index = (current_color == TRANSPARENT(dpy, screen) ? 0 : current_color + 1);
  1341.   
  1342.   colorTable = PWGetColorTable(pixmap_widget);
  1343.   sprintf(message, "Color `%s' [%d] grey scale 4 display name:", 
  1344.       colorTable[index]->c_name, current_color);
  1345.   
  1346.   if (PopupDialog(input_dialog, message, 
  1347.           (colorTable[index]->g4_name ? 
  1348.            colorTable[index]->g4_name : ""), 
  1349.           &g4_name,
  1350.           XtGrabExclusive) == Okay)
  1351.   {
  1352.       XColor color;
  1353.       
  1354.       if (!XParseColor(dpy, cmap, g4_name, &color))
  1355.     {
  1356.       fprintf(stderr, "Warning: color %s could not be parsed!\n",
  1357.           g4_name);
  1358.     }
  1359.       else
  1360.     PWUpdateColorInTable(pixmap_widget, 
  1361.                  current_color,
  1362.                  colorTable[index]->symbol,
  1363.                  colorTable[index]->s_name,
  1364.                  colorTable[index]->m_name,
  1365.                  g4_name,
  1366.                  colorTable[index]->g_name,
  1367.                  colorTable[index]->c_name);
  1368.   }
  1369. }
  1370.  
  1371. void DoGreyName()
  1372. {
  1373.   char *g_name;
  1374.   char message[80];
  1375.   /* index in colorTable is 0 for transparent, pixel+1 for other colors */
  1376.   int index = (current_color == TRANSPARENT(dpy, screen) ? 0 : current_color + 1);
  1377.   
  1378.   colorTable = PWGetColorTable(pixmap_widget);
  1379.   sprintf(message, "Color `%s' [%d] grey scale display name:", 
  1380.       colorTable[index]->c_name, current_color);
  1381.   
  1382.   if (PopupDialog(input_dialog, message, 
  1383.           (colorTable[index]->g_name ? 
  1384.            colorTable[index]->g_name : ""), 
  1385.           &g_name,
  1386.           XtGrabExclusive) == Okay)
  1387.   {
  1388.       XColor color;
  1389.       
  1390.       if (!XParseColor(dpy, cmap, g_name, &color))
  1391.     {
  1392.       fprintf(stderr, "Warning: color %s could not be parsed!\n",
  1393.           g_name);
  1394.     }
  1395.       else
  1396.     PWUpdateColorInTable(pixmap_widget, 
  1397.                  current_color,
  1398.                  colorTable[index]->symbol,
  1399.                  colorTable[index]->s_name,
  1400.                  colorTable[index]->m_name,
  1401.                  colorTable[index]->g4_name,
  1402.                  g_name,
  1403.                  colorTable[index]->c_name);
  1404.   }
  1405. }
  1406.  
  1407. void DoColorName()
  1408. {
  1409.   char *c_name;
  1410.   char message[80];
  1411.   /* index in colorTable is 0 for transparent, pixel+1 for other colors */
  1412.   int index = (current_color == TRANSPARENT(dpy, screen) ? 0 : current_color + 1);
  1413.   
  1414.   colorTable = PWGetColorTable(pixmap_widget);
  1415.   sprintf(message, "Color `%s' [%d] color display name:", 
  1416.       colorTable[index]->c_name, current_color);
  1417.  RetryColorCname:
  1418.   if ((PopupDialog(input_dialog, message, 
  1419.            (colorTable[index]->c_name ? 
  1420.             colorTable[index]->c_name : ""), 
  1421.            &c_name,
  1422.            XtGrabExclusive) == Okay) && (c_name))
  1423.   {
  1424.       XColor color;
  1425.       
  1426. /*      if (strcasecmp(c_name, NoColorName) == 0)
  1427.     {
  1428.       if (PopupDialog(error_dialog, "Can't rename color to None",
  1429.               NULL, NULL, XtGrabExclusive) == Retry)
  1430.         goto RetryColorCname;
  1431.     }
  1432.       else*/ if ((strcasecmp(c_name, NoColorName) != 0) &&
  1433.          (!XParseColor(dpy, cmap, c_name, &color)))
  1434.     {
  1435.       fprintf(stderr, "Warning: color %s could not be parsed!\n",
  1436.           c_name);
  1437.     }
  1438.       else
  1439.     {
  1440.       FixColorMenuLabel(colorTable[index]->c_name, c_name);
  1441.       PWUpdateColorInTable(pixmap_widget, 
  1442.                    current_color,
  1443.                    colorTable[index]->symbol,
  1444.                    colorTable[index]->s_name,
  1445.                    colorTable[index]->m_name,
  1446.                    colorTable[index]->g4_name,
  1447.                    colorTable[index]->g_name,
  1448.                    c_name);
  1449.     }
  1450.     }
  1451. }
  1452.  
  1453. void SwitchImage()
  1454. {
  1455.     if (image_visible) {
  1456.       XtPopdown(image_shell);
  1457.       image_visible = False;
  1458.     }
  1459.     else {
  1460.       Position image_x, image_y;
  1461.       int n;
  1462.       Arg wargs[3];
  1463.       
  1464.       XtTranslateCoords(XtParent(pixmap_widget), 
  1465.             10, 10, &image_x, &image_y);
  1466.       
  1467.       n = 0;
  1468.       XtSetArg(wargs[n], XtNx, image_x); n++;
  1469.       XtSetArg(wargs[n], XtNy, image_y); n++;
  1470.       XtSetValues(image_shell, wargs, n);
  1471.       
  1472.       image_visible = True;
  1473.       
  1474.       XtPopup(image_shell, XtGrabNone);
  1475.       unsetKillfromWM(image_shell);
  1476.       FixImage(pixmap_widget, NULL, NULL);
  1477.     }
  1478. }
  1479.  
  1480. void SwitchGrid()
  1481. {
  1482.   PWSwitchGrid(pixmap_widget);
  1483. }
  1484.  
  1485. void SwitchAxes()
  1486. {
  1487.   PWSwitchAxes(pixmap_widget);
  1488. }
  1489.  
  1490. void SwitchProportional()
  1491. {
  1492.   PWSwitchProportional(pixmap_widget);
  1493. }
  1494.  
  1495. void SwitchZoom()
  1496. {
  1497.   if (PWQueryZooming(pixmap_widget)) {
  1498.     PWZoomOut(pixmap_widget);
  1499.     PWChangeNotify(pixmap_widget, NULL, NULL);
  1500.   }
  1501.   else {
  1502.     if (PWQueryMarked(pixmap_widget)) {
  1503.       PWStoreToBuffer(pixmap_widget);
  1504.       PWZoomMarked(pixmap_widget);
  1505.       PWChangeNotify(pixmap_widget, NULL, NULL);
  1506.     }
  1507.     else {
  1508.       PWEngageRequest(pixmap_widget, ZoomInRequest, False, Plain);
  1509.     }
  1510.   }
  1511. }
  1512.  
  1513. void DoZoomIn()
  1514. {
  1515.     Dimension square_size, inc = 2;
  1516.     Arg args[2];
  1517.  
  1518.     XtSetArg(args[0], XtNsquareSize, &square_size);
  1519.     XtGetValues(pixmap_widget, args, 1);
  1520.     square_size += inc;
  1521.     XtSetArg(args[0], XtNsquareSize, square_size);
  1522.     XtSetValues(pixmap_widget, args, 1);
  1523. #ifdef USE_ATHENA
  1524.     PWRedraw(pixmap_widget);
  1525. #endif
  1526. }
  1527.  
  1528. void DoZoomOut()
  1529. {
  1530.     Dimension square_size, inc = 2;
  1531.     Arg args[2];
  1532.  
  1533.     XtSetArg(args[0], XtNsquareSize, &square_size);
  1534.     XtGetValues(pixmap_widget, args, 1);
  1535.     square_size -= inc;
  1536.     if (square_size > 0)
  1537.       {
  1538.       XtSetArg(args[0], XtNsquareSize, square_size);
  1539.       XtSetValues(pixmap_widget, args, 1);
  1540. #ifdef USE_ATHENA
  1541.       PWRedraw(pixmap_widget);
  1542. #endif
  1543.       }
  1544. }
  1545.  
  1546. void DoZoomFactor()
  1547. {
  1548.     Dimension square_size;
  1549.     Arg args[2];
  1550.     char message[80], buffer[80], *returned;
  1551.  
  1552.     XtSetArg(args[0], XtNsquareSize, &square_size);
  1553.     XtGetValues(pixmap_widget, args, 1);
  1554.     sprintf(buffer, "%d", square_size);
  1555.     strcpy(message, "Set Zoom Factor:");
  1556.     if ((PopupDialog(input_dialog, message, 
  1557.              buffer, &returned, XtGrabExclusive) == Okay) &&
  1558.     (returned))
  1559.       {
  1560.       if ((square_size = atoi(returned)) > 0)
  1561.         {
  1562.         XtSetArg(args[0], XtNsquareSize, square_size);
  1563.         XtSetValues(pixmap_widget, args, 1);
  1564. #ifdef USE_ATHENA
  1565.         PWRedraw(pixmap_widget);
  1566. #endif
  1567.         }
  1568.       }
  1569. }
  1570.  
  1571.     
  1572. void DoResize()
  1573. {
  1574.   char x;
  1575.   int width, height;
  1576.  
  1577.   format = "";
  1578.  RetryResize:
  1579.   if (PopupDialog(input_dialog, "Resize to WIDTHxHEIGHT:", 
  1580.           format, &format, XtGrabExclusive) == Okay) {
  1581.     sscanf(format, "%d%c%d", &width, &x, &height);
  1582.     if ((width >0) && (height > 0) && (x == 'x')) {
  1583.       PWStoreToBuffer(pixmap_widget);
  1584.       PWResize(pixmap_widget, (Dimension)width, (Dimension)height);
  1585.       PWChangeNotify(pixmap_widget, NULL, NULL);
  1586.       PWSetChanged(pixmap_widget);
  1587.       FixStatus();
  1588.     }
  1589.     else {
  1590.       sprintf(message, "Wrong format: %s", format);
  1591.       if (PopupDialog(error_dialog, message, 
  1592.               NULL, NULL, XtGrabExclusive) == Retry)
  1593.     goto RetryResize;
  1594.     }
  1595.   }
  1596. }
  1597.  
  1598. void DoRescale()
  1599. {
  1600.   char x;
  1601.   int width, height;
  1602.  
  1603.   format = "";
  1604.  RetryRescale:
  1605.   if (PopupDialog(input_dialog, "Rescale to WIDTHxHEIGHT:", 
  1606.           format,    &format, XtGrabExclusive) == Okay) {
  1607.     sscanf(format, "%d%c%d", &width, &x, &height);
  1608.     if ((width >0) && (height > 0) && (x == 'x')) {
  1609.       PWStoreToBuffer(pixmap_widget);
  1610.       PWRescale(pixmap_widget, (Dimension)width, (Dimension)height);
  1611.       PWChangeNotify(pixmap_widget, NULL, NULL);
  1612.       PWSetChanged(pixmap_widget);
  1613.       FixStatus();
  1614.     }
  1615.     else {
  1616.       sprintf(message, "Wrong format: %s", format);
  1617.       if (PopupDialog(error_dialog, message, 
  1618.               NULL, NULL, XtGrabExclusive) == Retry)
  1619.     goto RetryRescale;
  1620.     }
  1621.   }
  1622. }
  1623.  
  1624.  
  1625. void DoCut()
  1626. {
  1627.   PWStore(pixmap_widget);
  1628.   PWStoreToBuffer(pixmap_widget);
  1629.   PWClearMarked(pixmap_widget);
  1630.   PWUnmark(pixmap_widget);
  1631.   PWChangeNotify(pixmap_widget, NULL, NULL);
  1632. }
  1633.  
  1634. void DoCopy()
  1635. {
  1636.   PWStore(pixmap_widget);
  1637.   PWUnmark(pixmap_widget);
  1638. }
  1639.  
  1640. void DoPaste()
  1641. {
  1642.   PWEngageRequest(pixmap_widget, RestoreRequest, False, Plain);
  1643. }
  1644.  
  1645. void DoCrop()
  1646. {
  1647.   if (!PWQueryMarked(pixmap_widget) && !PWQueryStored(pixmap_widget)) return;
  1648.   
  1649.   PWStoreToBuffer(pixmap_widget);
  1650.   PWRotateBufferAndImage(pixmap_widget);
  1651. #ifdef USE_ATHENA
  1652.   PWRedraw(pixmap_widget);
  1653. #endif
  1654. }
  1655.  
  1656. void InfoCallback()
  1657. {
  1658.     PopupDialog(info_dialog, info,
  1659.         NULL, NULL, XtGrabExclusive);
  1660. }
  1661.  
  1662.  
  1663.  
  1664. #include "PortEditor.c"
  1665. #include "ExtEditor.c"
  1666.  
  1667.  
  1668. /* PixmapWidget callback for drawing a point */
  1669. #if NeedFunctionPrototypes
  1670. void DrawPointExtensions(Widget w, Position x, Position y, int value )
  1671. #else
  1672. void DrawPointExtensions( w, x, y, value )
  1673.     Widget    w;
  1674.     Position    x;
  1675.     Position    y;
  1676.     int        value;
  1677. #endif
  1678. {
  1679.     DrawIfPort( w, x, y, value );
  1680. }
  1681.  
  1682.  
  1683. /* PixmapWidget callback for redrawing/refreshing everything */ 
  1684.  
  1685. #if NeedFunctionPrototypes
  1686. void DrawExtensions(Widget w, int value )
  1687. #else
  1688. void DrawExtensions( w, value )
  1689.     Widget w;
  1690.     int       value;
  1691. #endif
  1692. {
  1693.     RedrawPorts( w, value );
  1694. }
  1695.  
  1696.  
  1697. /* PixmapWidget callback for translating by dx, dy */
  1698.  
  1699. #if NeedFunctionPrototypes
  1700. void TranslateExtensions(Widget w, Position dx, Position dy )
  1701. #else
  1702. void TranslateExtensions( w, dx, dy )
  1703.     Widget    w;
  1704.     Position    dx;
  1705.     Position    dy;
  1706. #endif
  1707. {
  1708.     TranslatePorts( w, dx, dy );
  1709. }
  1710.  
  1711.  
  1712. /* PixmapWidget callback for rotating right/left */
  1713.  
  1714. #if NeedFunctionPrototypes
  1715. void RotateExtensions(Widget w, enum RotateDirection direction )
  1716. #else
  1717. void RotateExtensions( w, direction )
  1718.     Widget            w;
  1719.     enum RotateDirection    direction;
  1720. #endif
  1721. {
  1722.     RotatePorts( w, direction );
  1723. }
  1724.  
  1725.  
  1726. /* PixmapWidget callback for flipping horizontal/vertical */
  1727.  
  1728. #if NeedFunctionPrototypes
  1729. void FlipExtensions(Widget w, enum FlipAxis axis )
  1730. #else
  1731. void FlipExtensions( w, axis )
  1732.     Widget        w;
  1733.     enum FlipAxis    axis;
  1734. #endif
  1735. {
  1736.     FlipPorts( w, axis );
  1737. }
  1738.  
  1739.  
  1740.  
  1741. /* loading pixmap editors colors */
  1742. loadPixEditColors()
  1743. {
  1744.   FILE *colorfile;
  1745.   static char *fname = ".pixmap";
  1746.   char filename[256];
  1747.  
  1748.  
  1749.   /* load transparent color */
  1750.   colorToAdd(pixmap_widget, TRANSPARENT(dpy, screen), NoColorName);
  1751.   PWUseColorInTable(pixmap_widget, TRANSPARENT(dpy, screen), NULL, NoColorName, NULL,
  1752.             NULL, NULL, NoColorName);
  1753.   
  1754.   /* first try to open in local dir */
  1755.   if (!(colorfile = fopen(fname, "r")))
  1756.     { /* try in homedir */
  1757.       sprintf(filename, "%s/%s", getenv("HOME"), fname);
  1758.       if (!(colorfile = fopen(filename, "r")))
  1759.     { /* try in X11 lib dir */
  1760.       sprintf(filename, "/usr/lib/X11/app-defaults/%s", fname);
  1761.       colorfile = fopen(filename, "r");
  1762.     }
  1763.     }
  1764.   
  1765.   if (colorfile) 
  1766.     { /* parse it, i.e., read name, try to alloc in cmap, add menu entry */
  1767.       char cname[512];
  1768.       int status;
  1769.       XColor color;
  1770.       
  1771.       while ((status = fscanf(colorfile,"%[^\n]\n", cname)) && (status != EOF))
  1772.     {
  1773.       if (!XParseColor(dpy, cmap, cname, &color)) continue;
  1774.       if (!XAllocColor(dpy, cmap, &color))
  1775.         {
  1776.           fprintf(stderr, "Warning: color %s could not be allocated!",
  1777.               cname);
  1778.           continue;
  1779.         }
  1780.       else
  1781.         {
  1782.           colorToAdd(pixmap_widget,  color.pixel, 
  1783.              ((cname[0] == '#') ? 
  1784.               xpmGetRgbName(rgb_table, max_ncolors, 
  1785.                      (int) color.red,
  1786.                      (int) color.green,
  1787.                      (int) color.blue) : cname));
  1788.           PWUseColorInTable(pixmap_widget,  color.pixel, NULL, NULL,
  1789.                 NULL, NULL, NULL,
  1790.                 ((cname[0] == '#') ? 
  1791.                  xpmGetRgbName(rgb_table, max_ncolors, 
  1792.                            (int) color.red,
  1793.                            (int) color.green,
  1794.                            (int) color.blue) : cname));
  1795.         }
  1796.     }
  1797.       fclose(colorfile);
  1798.     }
  1799.   else
  1800.     { /* load min(ncolors, 30) allocated in colormap */
  1801.       int i;
  1802.       
  1803.       for (i = 0; i < (ncolors > 30 ? 30 : ncolors); i++)
  1804.     {
  1805.       XColor color;
  1806.       color.pixel = (Pixel)i;
  1807.       XQueryColor(dpy, DefaultColormap(dpy, screen), &color);
  1808.       
  1809.       colorToAdd(pixmap_widget,  color.pixel,
  1810.              xpmGetRgbName(rgb_table, max_ncolors, 
  1811.                    (int) color.red,
  1812.                    (int) color.green,
  1813.                    (int) color.blue));
  1814.       PWUseColorInTable(pixmap_widget,  color.pixel, NULL, NULL,
  1815.                 NULL, NULL, NULL,
  1816.                 xpmGetRgbName(rgb_table, max_ncolors, 
  1817.                       (int) color.red,
  1818.                       (int) color.green,
  1819.                       (int) color.blue));
  1820.       }
  1821.     }
  1822. }
  1823.  
  1824. void MakeMenuPanel(father, menu, num, callback)
  1825.      Widget father;
  1826.      ButtonRec       menu[];
  1827.      Cardinal       num;
  1828.      XtCallbackProc callback;
  1829. {
  1830.     Widget    bw;
  1831.     int        i;
  1832.  
  1833.     for (i = 0; i < num; i++) {
  1834. #ifndef USE_ATHENA
  1835.     if (menu[i].id == Dummy)
  1836.       bw = XmCreateSeparatorGadget(father, menu[i].name, NULL, 0);
  1837.     else if (menu[i].trap == TOGGLE)
  1838.       {
  1839.           bw = XmCreateToggleButtonGadget(father, menu[i].name, NULL, 0);
  1840.           XtAddCallback(bw, XmNvalueChangedCallback, callback,
  1841.                 (XtPointer)&menu[i].id);
  1842.       }
  1843.     else
  1844.       {
  1845.           bw =  XmCreatePushButtonGadget(father, menu[i].name, NULL, 0);
  1846.           XtAddCallback(bw, XmNactivateCallback, callback,
  1847.                 (XtPointer)&menu[i].id);
  1848.       }
  1849.     menu[i].widget = bw;
  1850.     XtManageChild(bw);
  1851. #else
  1852.         bw = XtCreateManagedWidget( menu[i].name,
  1853.                                     ((menu[i].id != Dummy) ?
  1854.                                       smeBSBObjectClass : smeLineObjectClass),
  1855.                                     father, NULL, 0);
  1856.         XtAddCallback( bw, XtNcallback, callback, (XtPointer) &menu[i].id );
  1857.         menu[i].widget = bw;
  1858. #endif USE_ATHENA
  1859.     }
  1860. }
  1861.  
  1862. static Widget
  1863. MakeMenu( menubar, menuName, buttonName, menu, num, callback )
  1864.     Widget       menubar;
  1865.     String       menuName;
  1866.     String       buttonName;
  1867.     ButtonRec       menu[];
  1868.     Cardinal       num;
  1869.     XtCallbackProc callback;
  1870. {
  1871.     Widget    mw;
  1872.     Widget    bw;
  1873.     int        i;
  1874.  
  1875. #ifndef USE_ATHENA
  1876.     Arg wargs[1];
  1877.  
  1878.     mw = XmCreatePulldownMenu(menubar, menuName, NULL, 0);
  1879.  
  1880.     XtSetArg(wargs[0], XmNsubMenuId, mw);
  1881.     bw = XmCreateCascadeButtonGadget(menubar, buttonName, wargs, 1);
  1882.     XtManageChild(bw);
  1883. #else
  1884.     mw = XtCreatePopupShell( menuName, simpleMenuWidgetClass,
  1885.                              menubar, NULL, 0 );
  1886.  
  1887.     bw = XtCreateManagedWidget( buttonName, menuButtonWidgetClass, 
  1888.                                 menubar, NULL, 0 );
  1889. #endif USE_ATHENA
  1890.     
  1891.     MakeMenuPanel(mw, menu, num, callback);
  1892.  
  1893.     return mw;
  1894. }
  1895.  
  1896.  
  1897.  
  1898. void main(argc, argv)
  1899.     int    argc;
  1900.     char  *argv[];
  1901. {
  1902.     int i, n;
  1903.     Arg wargs[5];
  1904.     Widget w, pview_widget, cview_widget, vpane_widget;
  1905. #ifndef USE_ATHENA
  1906.     Widget formh;
  1907.     static int Resize_id = Resize, Filename_id = Filename;
  1908. #else USE_ATHENA
  1909.     Widget radio_group; XtPointer radio_data;
  1910. #endif
  1911.     int x, y;
  1912.     unsigned int width = 0, height = 0;
  1913.     
  1914.     top_widget = XtAppInitialize(&pixmap_context, "Pixmap", 
  1915.                  options, XtNumber(options), 
  1916.                  &argc, argv, NULL, NULL, 0);
  1917.  
  1918.     if (argc > 1) {
  1919.       if ((argc ==3) && (strcmp(argv[1], "-size") == 0))
  1920.       XParseGeometry(argv[2], &x, &y, &width, &height);
  1921.       else
  1922.     {
  1923.       fprintf(stderr, "%s %s", argv[0], usage);
  1924.       exit (-1);
  1925.     }
  1926.     }
  1927.  
  1928.     /* some intializations */
  1929.     dpy = XtDisplay(top_widget);
  1930.     screen = DefaultScreen(dpy);
  1931.     ncolors = DisplayCells(dpy, screen);
  1932. #ifdef DEBUG
  1933.     printf("Num colors %d\n",ncolors);
  1934.     printf("Transparent entry in colormap %d\n", TRANSPARENT(dpy, screen));
  1935.     XSynchronize(dpy, True);
  1936. #endif DEBUG
  1937.     cmap = DefaultColormap(dpy,screen);
  1938.     colorInMenu = (char *) XtMalloc((ncolors + 1)*sizeof(char)); /* +1 for
  1939.                                     transp. */
  1940.     bzero(colorInMenu, (ncolors + 1)*sizeof(char));
  1941.     max_ncolors = xpmReadRgbNames(rgb_fname, rgb_table);
  1942.  
  1943. #ifdef USE_ATHENA
  1944.     check_mark = XCreateBitmapFromData(XtDisplay(top_widget),
  1945.                       RootWindowOfScreen(XtScreen(top_widget)),
  1946.                       xlogo16_bits, 
  1947.                       xlogo16_width, 
  1948.                       xlogo16_height);
  1949. #endif
  1950.     XtAppAddActions(pixmap_context, actions_table, XtNumber(actions_table));
  1951. #ifndef USE_ATHENA
  1952.     parent_widget = XtCreateManagedWidget("parent", xmFormWidgetClass,
  1953.                      top_widget, NULL, 0);
  1954.  
  1955.     formy_widget = XmCreateMenuBar(parent_widget, "formy", NULL, 0);
  1956.     XtManageChild(formy_widget);
  1957.  
  1958.     infoButton_widget = XmCreateCascadeButtonGadget(formy_widget, 
  1959.                          "infoButton", NULL, 0);
  1960.     XtManageChild(infoButton_widget);
  1961.     XtAddCallback(infoButton_widget, XmNactivateCallback, InfoCallback, NULL);
  1962.     
  1963. #else USE_ATHENA
  1964.  
  1965.     parent_widget = XtCreateManagedWidget("parent", panedWidgetClass,
  1966.                      top_widget, NULL, 0);
  1967.  
  1968.     formy_widget = XtCreateManagedWidget("formy", formWidgetClass,
  1969.                        parent_widget, NULL, 0);
  1970.  
  1971.     infoButton_widget = XtCreateManagedWidget("infoButton",
  1972.                     commandWidgetClass, 
  1973.                     formy_widget, NULL, 0);
  1974.     XtAddCallback(infoButton_widget, XtNcallback, InfoCallback, NULL);
  1975. #endif
  1976.  
  1977.     MakeMenu(formy_widget, "fileMenu", "fileButton",
  1978.          file_menu, XtNumber(file_menu), TheCallback);
  1979.         
  1980.     MakeMenu(formy_widget, "editMenu", "editButton",
  1981.              edit_menu, XtNumber(edit_menu), TheCallback );
  1982.  
  1983.     MakeMenu(formy_widget, "colorMenu", "colorButton",
  1984.              color_menu, XtNumber(color_menu), TheCallback );
  1985.  
  1986.     extensionMenu_widget = 
  1987.       MakeMenu(formy_widget, "extensionMenu", "extensionButton",
  1988.                extension_menu, XtNumber(extension_menu),
  1989.            ExtensionMenuCallback);
  1990.  
  1991. #ifndef USE_ATHENA
  1992.     status_widget = XmCreateCascadeButtonGadget(formy_widget, "status",
  1993.                                 NULL, 0);
  1994.     XtManageChild(status_widget);
  1995.     XtAddCallback(status_widget, XmNactivateCallback, TheCallback, 
  1996.                   &Filename_id);
  1997.     statusb_widget = XmCreateCascadeButtonGadget(formy_widget, "statusb",
  1998.                                   NULL, 0);
  1999.     XtManageChild(statusb_widget);
  2000.     XtAddCallback(statusb_widget, XmNactivateCallback, TheCallback, 
  2001.                   &Resize_id);
  2002.  
  2003.     n = 0;
  2004.     XtSetArg(wargs[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
  2005.     XtSetArg(wargs[n], XmNtopWidget, formy_widget); n++;
  2006.     pane_widget = XmCreateForm(parent_widget, "pane", wargs, n);
  2007.     XtManageChild(pane_widget);
  2008.  
  2009.     form_widget = XmCreateRadioBox(pane_widget, "form", NULL, 0);
  2010.     XtSetArg(wargs[0], XmNisHomogeneous, False);
  2011.     XtSetValues(form_widget, wargs, 1);
  2012.     XtManageChild(form_widget);
  2013.         
  2014.     for (i = 0; i < XtNumber(buttons); i++) {
  2015.       if (buttons[i].trap == TOGGLE)
  2016.     {
  2017.       w = XmCreateToggleButtonGadget(form_widget, buttons[i].name, 
  2018.                      NULL, 0);
  2019.       XtAddCallback(w, XmNvalueChangedCallback, TheCallback, 
  2020.             &buttons[i].id);
  2021.     }
  2022.       else 
  2023.     {
  2024.       if ((!strcmp(buttons[i].name, "flipHoriz")) ||
  2025.           (!strcmp(buttons[i].name, "left")) ||
  2026.           (!strcmp(buttons[i].name, "rotateLeft")))
  2027.         {
  2028.           formh = form_widget;
  2029.           form_widget = XmCreateRowColumn(formh, "formh", NULL, 0);
  2030.           XtManageChild(form_widget);
  2031.         }
  2032.       
  2033.       w = XmCreatePushButtonGadget(form_widget, buttons[i].name, NULL, 0);
  2034.       XtAddCallback(w, XmNactivateCallback, TheCallback, &buttons[i].id);
  2035.  
  2036.       if ((!strcmp(buttons[i].name, "flipVert")) ||
  2037.           (!strcmp(buttons[i].name, "right")) ||
  2038.           (!strcmp(buttons[i].name, "rotateRight")))
  2039.         form_widget = formh;
  2040.     }
  2041.  
  2042.       buttons[i].widget = w;
  2043.       XtManageChild(w);
  2044.       
  2045.       if (buttons[i].id == Point) 
  2046.     XmToggleButtonGadgetSetState(buttons[i].widget, True, False);
  2047.     }
  2048.  
  2049.     n = 0;
  2050.     XtSetArg(wargs[n], XmNleftAttachment, XmATTACH_WIDGET); n++;
  2051.     XtSetArg(wargs[n], XmNleftWidget, form_widget); n++;
  2052.     vpane_widget = (Widget) XmCreatePanedWindow(pane_widget, "vPane", 
  2053.                         wargs, n);
  2054.     XtManageChild(vpane_widget);
  2055.  
  2056.     /* the color pane should be created before the pixmap widget as the
  2057.        creation of the pixmap widget will ``add'' a new color in the pane */
  2058.     n = 0;
  2059.     cview_widget = (Widget)XmCreateScrolledWindow(vpane_widget, "colorView",
  2060.                          wargs, n);
  2061.     XtManageChild(cview_widget);
  2062.     n = 0;
  2063.     color_pane_widget = XmCreateRowColumn(cview_widget, "colorPane",
  2064.                       wargs, n);
  2065.     XtManageChild(color_pane_widget);
  2066.     XmScrolledWindowSetAreas(cview_widget,
  2067.                  XmCreateScrollBar(cview_widget, "cviewHS",
  2068.                            NULL, 0),
  2069.                  XmCreateScrollBar(cview_widget, "cviewVS",
  2070.                            NULL, 0),
  2071.                  color_pane_widget);
  2072.  
  2073.     n = 0;
  2074.     pview_widget = (Widget)XmCreateScrolledWindow(vpane_widget, "pixmapView",
  2075.                          wargs, n);
  2076.     XtManageChild(pview_widget);
  2077.  
  2078. #else USE_ATHENA
  2079.  
  2080.     status_widget = XtCreateManagedWidget("status", labelWidgetClass,
  2081.                       formy_widget, NULL, 0);
  2082.  
  2083.     pane_widget = XtCreateManagedWidget("pane", panedWidgetClass,
  2084.                     parent_widget, NULL, 0);
  2085.  
  2086.     form_widget = XtCreateManagedWidget("form", formWidgetClass, 
  2087.                     pane_widget, NULL, 0);
  2088.         
  2089.     for (i = 0; i < XtNumber(buttons); i++) {
  2090.     w = XtCreateManagedWidget(buttons[i].name, 
  2091.                   ((buttons[i].trap == TOGGLE) ? 
  2092.                    toggleWidgetClass : commandWidgetClass),
  2093.                   form_widget, NULL, 0);
  2094.     XtAddCallback(w,
  2095.               XtNcallback,
  2096.               TheCallback,
  2097.               &buttons[i].id);
  2098.  
  2099.     buttons[i].widget = w;
  2100.  
  2101.     if (buttons[i].id == Point) {
  2102.         radio_group = buttons[i].widget;
  2103.         radio_data  = buttons[i].name;
  2104.     }
  2105.     }
  2106.  
  2107.     vpane_widget = XtCreateManagedWidget("vPane", panedWidgetClass,
  2108.                      pane_widget, NULL, 0);
  2109.  
  2110.     /* the color pane should be created before the pixmap widget as the
  2111.        creation of the pixmap widget will ``add'' a new color in the pane */
  2112.     cview_widget = XtCreateManagedWidget("colorView", viewportWidgetClass,
  2113.                      vpane_widget, NULL, 0);
  2114.  
  2115.     color_pane_widget = XtCreateManagedWidget("colorPane", boxWidgetClass,
  2116.                           cview_widget, NULL, 0);
  2117.  
  2118.     pview_widget = XtCreateManagedWidget("pixmapView", viewportWidgetClass,
  2119.                      vpane_widget, NULL, 0);
  2120. #endif
  2121.  
  2122.     /* foreach extension editor, create and manage editor buttons */ 
  2123.     CreatePortEditorButtons(form_widget,
  2124. #ifndef USE_ATHENA
  2125.                 NULL);
  2126. #else
  2127.                 radio_group);
  2128. #endif
  2129.     ManagePortEditorButtons(True); 
  2130.  
  2131.     n = 0;
  2132.     XtSetArg(wargs[n], XtNaddColorNtfyProc, colorToAdd); n++;
  2133.     XtSetArg(wargs[n], XtNextensionNtfyProc, FixExtensionMenu); n++;
  2134.     if (width) XtSetArg(wargs[n], XtNpixmapWidth, width), n++;
  2135.     if (height) XtSetArg(wargs[n], XtNpixmapHeight, height), n++;
  2136.     pixmap_widget = XtCreateManagedWidget("pixmap", pixmapWidgetClass,
  2137.                       pview_widget, wargs, n);
  2138.  
  2139.     /* register extension callbacks with pixmap widget */
  2140.     PWSetDrawPointProc(pixmap_widget, DrawPointExtensions);
  2141.     PWSetRedrawProc(   pixmap_widget, DrawExtensions);
  2142.     PWSetTranslateProc(pixmap_widget, TranslateExtensions);
  2143.     PWSetRotateProc(   pixmap_widget, RotateExtensions);
  2144.     PWSetFlipProc(     pixmap_widget, FlipExtensions);
  2145.  
  2146.  
  2147. #ifndef USE_ATHENA
  2148.     XmScrolledWindowSetAreas(pview_widget,
  2149.                  XmCreateScrollBar(pview_widget, "pviewHS",
  2150.                            NULL, 0),
  2151.                  XmCreateScrollBar(pview_widget, "pviewVS",
  2152.                            NULL, 0),
  2153.                  pixmap_widget);
  2154.  
  2155. #endif 
  2156.  
  2157.     XtSetKeyboardFocus(top_widget, pixmap_widget);
  2158.     
  2159.     PWSetForeground(pixmap_widget,BlackPixel(dpy, screen));
  2160.     current_color = BlackPixel(dpy, screen);
  2161.     
  2162.     XtRealizeWidget(top_widget);
  2163.  
  2164.     loadPixEditColors();
  2165.     
  2166.     image_shell = XtCreatePopupShell("image", transientShellWidgetClass,
  2167.                      top_widget, NULL, 0);
  2168. #ifndef USE_ATHENA
  2169.     XtSetArg(wargs[0], XmNlabelString, 
  2170.          XmStringCreateLtoR("", XmSTRING_DEFAULT_CHARSET));
  2171.     image_widget = XmCreateLabel(image_shell, "label", wargs, 1);
  2172.     XtManageChild(image_widget);
  2173. #else USE_ATHENA
  2174.     image_widget = XtCreateManagedWidget("label", labelWidgetClass,
  2175.                      image_shell, NULL, 0);
  2176.     XtRealizeWidget(image_shell);
  2177. #endif
  2178.  
  2179.     Notify(pixmap_widget, FixImage);
  2180.     ColorNotify(pixmap_widget, (UseColorNotifyProc)FixColor);
  2181.  
  2182.     FixStatus();
  2183.     
  2184.     info_dialog  = CreateDialog(top_widget, "info", Okay);
  2185.     input_dialog = CreateDialog(top_widget, "input", Okay | Cancel);
  2186.     error_dialog = CreateDialog(top_widget, "error", Abort | Retry);    
  2187.     qsave_dialog = CreateDialog(top_widget, "qsave", Yes | No | Cancel);
  2188.     file_dialog  = CreateDialog(top_widget, "file", Okay | Cancel);
  2189.  
  2190.     extensionEditor = CreateExtensionEditor(top_widget, "extEditor");
  2191.  
  2192.     textOptions = CreateTextOptions(top_widget, "textOptions");
  2193.     PWSetFont(pixmap_widget, textOptions->font_struct);
  2194.     PWSetText(pixmap_widget, textOptions->text_string);
  2195.  
  2196. #ifdef USE_ATHENA
  2197.     XawToggleSetCurrent(radio_group, radio_data);
  2198. #endif
  2199.     PWEngageRequest(pixmap_widget, PointRequest, True, Plain);
  2200.  
  2201.     XtAppMainLoop(pixmap_context);
  2202. }
  2203.  
  2204.  
  2205.  
  2206.